home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 60.zip / BS1 part 60 / C mon v3 d3.adf / CMANV3_3.LHA / ACE9.lha / Devices / GameportDevice / Example4.c < prev    next >
C/C++ Source or Header  |  1992-04-27  |  17KB  |  497 lines

  1. /***********************************************************/
  2. /*                                                         */
  3. /* Amiga C Encyclopedia (ACE) V3.0      Amiga C Club (ACC) */
  4. /* -------------------------------      ------------------ */
  5. /*                                                         */
  6. /* Book:    ACM Devices                 Amiga C Club       */
  7. /* Chapter: Gameport Device             Tulevagen 22       */
  8. /* File:    Example4.c                  181 41  LIDINGO    */
  9. /* Author:  Anders Bjerin               SWEDEN             */
  10. /* Date:    92-04-27                                       */
  11. /* Version: 1.00                                           */
  12. /*                                                         */
  13. /*   Copyright 1992, Anders Bjerin - Amiga C Club (ACC)    */
  14. /*                                                         */
  15. /* Registered members may use this program freely in their */
  16. /*     own commercial/noncommercial programs/articles.     */
  17. /*                                                         */
  18. /***********************************************************/
  19.  
  20.  
  21.  
  22. /* This program demonstrates how you can use the */
  23. /* Gameport Device to read mouse events. The     */
  24. /* program will report any mouse movements or if */
  25. /* any buttons was pressed/released. If the user */
  26. /* has not used the mouse for one minnute, the   */
  27. /* program will terminate.                       */
  28. /*                                               */
  29. /* This example is "nice" to the system and does */
  30. /* everything according to the "rules".          */
  31. /*                                               */
  32. /* This example does not wait for something to   */
  33. /* happen, but is instead constantly trying to   */
  34. /* collect messages and can therefore continue   */
  35. /* do do something while the user is not using   */
  36. /* the mouse.                                    */
  37. /*                                               */
  38. /* NOTE! Since Intuition is already using port 1 */
  39. /* (the "mouse port") we have to use port 2. So  */
  40. /* remember to connect the mouse to port 2,      */
  41. /* before you run the program.                   */
  42.  
  43.  
  44.  
  45. #include <exec/types.h>         /* UWORD, STRPTR */
  46. #include <devices/gameport.h>   /* GPCT_MOUSE */
  47. #include <devices/inputevent.h> /* struct InputEvent */
  48.  
  49.  
  50.  
  51. #define RIGHTGAMEPORT 1 /* The "Joystick" port. */
  52. #define LEFTGAMEPORT  0 /* The "Mouse" port.    */
  53. #define MINX          5 /* The mouse must be moved at least 5 stepps */
  54. #define MINY          5 /* before a mouse event should occure.       */
  55.  
  56.  
  57.  
  58. /* Pointer to the Graphics library: */
  59. struct GfxBase *GfxBase;
  60.  
  61.  
  62.  
  63. struct IOStdReq *game_io_msg;    /* Pointer to our IOStdReq str.    */
  64. struct MsgPort   *game_msg_port; /* Pointer to our message port.    */
  65. BOOL deviceerror;                /* Have we opened the device, OK?  */
  66. int counter;
  67.  
  68.  
  69.  
  70. /* Declare some external functions:        */
  71. /* (We must otherwise do so much casting.) */
  72. extern struct MsgPort *CreatePort();
  73. extern struct IOStdReq *CreateStdIO();    
  74.  
  75.  
  76.  
  77. /* Declare all functions in this module: */
  78. void main();
  79. void PrintMouseData();       /* Print some information about the mouse.   */
  80. BYTE SetControllerType();    /* Set type of controller.                   */
  81. BYTE SetControllerTrigger(); /* Set trigger.                              */
  82. void SetControllerRead();    /* Prepare it so we can read.                */
  83. BYTE GetControllerType();    /* Get type of controller already coneccted. */
  84. void clean_up();             /* Cleanup, and quit.                        */
  85.  
  86.  
  87.  
  88. void main()
  89. {
  90.   /* Put all data in this structure: */
  91.   struct InputEvent gamedata;
  92.  
  93.   BYTE type;
  94.  
  95.  
  96.   /* Open the Graphics library: */
  97.   GfxBase = (struct GfxBase *)
  98.     OpenLibrary( "graphics.library", 0 );
  99.   if( !GfxBase )
  100.     clean_up( "ERROR! Could not open the Graphics library!" );
  101.  
  102.  
  103.   /* 1. Create a message port so the system can communicate with us: */
  104.   game_msg_port = CreatePort( 0, 0 );
  105.   if( !game_msg_port )
  106.     clean_up( "ERROR! Could not create message port!" );
  107.  
  108.  
  109.   /* 2. Allocate and initialize a new I/O request block.  */
  110.   /* It should use our new message port as reply port:    */
  111.   game_io_msg = CreateStdIO( game_msg_port );     
  112.   if( !game_io_msg )
  113.     clean_up( "ERROR! Could not allocate new I/O request block!" );
  114.  
  115.  
  116.   /* 3. Open the Game Port Device, use the right port: */
  117.   /*    (Intuition is already using the left port!)    */
  118.   deviceerror = OpenDevice( "gameport.device", RIGHTGAMEPORT, game_io_msg, 0xFFFF );
  119.   if( deviceerror )
  120.     clean_up( "ERROR! Could not open the Game Port Device!" );
  121.  
  122.  
  123.   /* 4. Check if some other task is already using the gameport: */
  124.   if( type = GetControllerType() )
  125.   {
  126.     switch( type )
  127.     {
  128.       case GPCT_MOUSE:
  129.         printf( "A mouse is connected to the port!\n" );
  130.         break;
  131.  
  132.       case GPCT_RELJOYSTICK:
  133.         printf( "A proportional joystick is connected to the port!\n" );
  134.         break;
  135.  
  136.       case GPCT_ABSJOYSTICK:
  137.         printf( "A normal joystick is connected to the port!\n" );
  138.         break;
  139.     }
  140.     
  141.     /* Do not close the device! If we do it, the other task will */
  142.     /* then not be able to use the gameport device either!       */
  143.     deviceerror = TRUE;
  144.     clean_up( "ERROR! Some other task is already using the Gameport!" );
  145.   }
  146.  
  147.  
  148.   /* 5. Set device type (mouse): */
  149.   if( SetControllerType( GPCT_MOUSE ) )
  150.     clean_up( "ERROR! Could not set device type!" );
  151.  
  152.  
  153.   /* 6. Set device trigger: */
  154.   if( SetControllerTrigger
  155.       (                            /* Report following events:    */
  156.         GPTF_DOWNKEYS|GPTF_UPKEYS, /* buttonpressed/released,     */ 
  157.         600,                       /* every 10th second,          */
  158.         MINX,                      /* X movements more than MINX, */
  159.         MINY                       /* Y movements more than MINY. */
  160.       )
  161.     )
  162.     clean_up( "ERROR! Could not set device trigger!" );
  163.  
  164.  
  165.   /* 7. Prepare the device to read: */
  166.   SetControllerRead( &gamedata );
  167.  
  168.  
  169.   /* 8. Do our request, and return without delay: */
  170.   SendIO( game_io_msg );
  171.  
  172.  
  173.   printf( "Gameport Device - Mouse Example - Waiting\n" );
  174.   /* Stay in the while loop until the user has not moved the */
  175.   /* mouse during the last minute: (6 times 10 seconds)      */
  176.   while( counter < 6 )
  177.   {
  178.     printf("Working...\n");
  179.  
  180.  
  181.     /* Try to collect a message: */
  182.     if( GetMsg( game_msg_port ) )
  183.     {
  184.       /* Print some information abut the mouse: */
  185.       PrintMouseData( &gamedata );
  186.  
  187.       /* We have now collected a mouse event, so prepare the */
  188.       /* gameport device again:                              */
  189.       SendIO( game_io_msg );
  190.     }
  191.   }
  192.  
  193.  
  194.   /* 9. NOTE! In this example we will have done one more SendIO()  */
  195.   /*    than GetMsg(), so before we quit we must try to cancel our */
  196.   /*    last command:                                              */
  197.   AbortIO( game_io_msg );
  198.  
  199.   /*    We must also make sure that there are no messages waiting at */
  200.   /*    our message port, so we try to collect as many messages as   */
  201.   /*    possible, until we can not collect any more:                 */
  202.   while( GetMsg( game_msg_port ) )
  203.     printf( "Collecting remaining messages...\n" );
  204.  
  205.  
  206.  
  207.   /* 10. Clean up nicely, and quit: */
  208.   clean_up( "The End!" );
  209. }    
  210.  
  211.  
  212.  
  213. /****************************************************************/
  214. /*                                                              */
  215. /* PrintMouseData() prints how many x/y counts the mouse has    */
  216. /* been moved, and if any buttons has been pressed or released. */
  217. /*                                                              */
  218. /* Synopsis: PrintMouseData( data );                            */
  219. /*                                                              */
  220. /* data:     (struct InputEvent *) Pointer to an InputEvent     */
  221. /*           structure which has previously been initialized.   */
  222. /*                                                              */
  223. /****************************************************************/
  224.  
  225. void PrintMouseData( data )
  226. struct InputEvent *data;
  227. {
  228.   WORD x;
  229.   WORD y;
  230.   UWORD code;
  231.  
  232.  
  233.   /* Collect data: */
  234.   x = data->ie_X;
  235.   y = data->ie_Y;
  236.   code = data->ie_Code;
  237.  
  238.  
  239.   /* Print: */
  240.   switch( code )
  241.   {
  242.     case IECODE_LBUTTON:
  243.       printf( "Left mouse button pressed\n" );
  244.       counter = 0;
  245.       break;
  246.  
  247.     case IECODE_RBUTTON:
  248.       printf( "Right mouse button pressed\n" );
  249.       counter = 0;
  250.       break;
  251.  
  252.     case IECODE_LBUTTON + IECODE_UP_PREFIX:
  253.       printf( "Left mouse button released\n" );
  254.       counter = 0;
  255.       break;
  256.  
  257.     case IECODE_RBUTTON + IECODE_UP_PREFIX:
  258.       printf( "Right mouse button released\n" );
  259.       counter = 0;
  260.       break;
  261.  
  262.     case IECODE_NOBUTTON:
  263.       /* Mouse moved, or timeout signal: */
  264.       if( x || y )
  265.       {
  266.         printf( "Mouse moved! delta x: %4d, delta y: %4d\n", x, y );
  267.         counter = 0;
  268.       }
  269.       else
  270.       {
  271.         printf( "10 seconds passed...\n" );
  272.         counter++;
  273.       }
  274.       break;
  275.   }
  276. }
  277.  
  278.  
  279.  
  280. /*************************************************************/
  281. /*                                                           */
  282. /* SetControllerType() tells the System what type of device  */
  283. /* (absolute joystick, proportional joystick or a mouse) you */
  284. /* want to handle.                                           */
  285. /*                                                           */
  286. /* Synopsis: error = SetControllerType( type, data );        */
  287. /*                                                           */
  288. /* error:    (BYTE) If the function could set controller     */
  289. /*           type it will return 0, else if something failed */
  290. /*           it will return an error number. For the moment  */
  291. /*           there exist only one type of error message and  */
  292. /*           that is GPDERR_SETCTYPE - the controller you    */
  293. /*           asked for is not valid at this time.            */
  294. /*                                                           */
  295. /* type:     (UBYTE) Type of controller you want to handle:  */
  296. /*           GPCT_MOUSE       - mouse                        */
  297. /*           GPCT_ABSJOYSTICK - absolute (normal) joystick   */
  298. /*           GPCT_RELJOYSTICK - proportional joystick        */
  299. /*                                                           */
  300. /*************************************************************/
  301.  
  302. BYTE SetControllerType( type )
  303. BYTE type;
  304. {
  305.   /* We want to set controller type: */
  306.   game_io_msg->io_Command = GPD_SETCTYPE;
  307.  
  308.   /* The message is only one byte long: */
  309.   game_io_msg->io_Length = 1;
  310.  
  311.   /* The data we want to send: */
  312.   game_io_msg->io_Data = (APTR) &type;  
  313.  
  314.   /* Do our request, and return when it is done: */
  315.   DoIO( game_io_msg );  
  316.  
  317.   /* Return any error message, or 0 if everything is OK: */
  318.   return( game_io_msg->io_Error );
  319. }
  320.  
  321.  
  322.  
  323. /****************************************************************/
  324. /*                                                              */
  325. /* SetControllerTrigger() tells the system what conditions      */
  326. /* should be fulfilled before a gameport event will occur.      */
  327. /* You can for example tell the device to only respond if       */
  328. /* the mouse has been moved more that 20 counts, and/or         */
  329. /* if nothing has happened within, let us say, 30 seconds,      */
  330. /* and/or a button has been pressed or released.                */
  331. /*                                                              */
  332. /* Synopsis: error = SetControllerTrigger( keys, time, x, y );  */
  333. /*                                                              */
  334. /* error:    (BYTE) If the function could set controller        */
  335. /*           trigger it will return 0, else if something failed */
  336. /*           it will return an error number. For the moment     */
  337. /*           there does not exist any special error code for    */
  338. /*           this function.                                     */
  339. /*                                                              */
  340. /* keys:     (UWORD) If you want that a gameport event is       */
  341. /*           triggered each time a button is pressed set the    */
  342. /*           flag "GPTF_DOWNKEYS", if you want that a gameport  */
  343. /*           event is triggered each time a button is           */
  344. /*           released set the flag "GPTF_UPKEYS". (If you want  */
  345. /*           both up and down key messages, set the binary      */
  346. /*           or ("|") operator between the flags. Example:      */
  347. /*           "GPTF_DOWNKEYS | GPTF_UPKEYS")                     */
  348. /*                                                              */
  349. /* time:     (UWORD) Set here how much time should pass before  */
  350. /*           a gameport event is triggered. The value is        */
  351. /*           in vertical blank units, which means 60 = 1 sec.   */
  352. /*           If you want to trigger an event each third minute  */
  353. /*           set the time value to 10800 (60 * 60 * 3). If      */
  354. /*           you do not want any time event, set time to 0.     */
  355. /*                                                              */
  356. /* x:        (UWORD) Set here how many x movements should be    */
  357. /*           reported, before a gameport event is triggered.    */
  358. /*           If you want to read a normal joystick, set x to 1. */
  359. /*                                                              */
  360. /* y:        (UWORD) Set here how many y movements should be    */
  361. /*           reported, before a gameport event is triggered.    */
  362. /*           If you want to read a normal joystick, set y to 1. */
  363. /*                                                              */
  364. /****************************************************************/
  365.  
  366. BYTE SetControllerTrigger( keys, timeout, xdelta, ydelta )
  367. UWORD keys;
  368. UWORD timeout;
  369. UWORD xdelta;
  370. UWORD ydelta;
  371. {
  372.   struct GamePortTrigger gpt;
  373.  
  374.   /* Set our requirements: */
  375.   gpt.gpt_Keys = keys;
  376.   gpt.gpt_Timeout = timeout;
  377.   gpt.gpt_XDelta = xdelta;
  378.   gpt.gpt_YDelta = ydelta;
  379.  
  380.   /* We want to set controller trigger: */
  381.   game_io_msg->io_Command = GPD_SETTRIGGER;
  382.  
  383.   /* The message is sizeof(struct GamePortTrigger) bytes long: */ 
  384.   game_io_msg->io_Length = sizeof( gpt );
  385.  
  386.   /* The data we want to send: */
  387.   game_io_msg->io_Data = (APTR) &gpt;
  388.  
  389.   /* Do our request and return when it is done: */
  390.   DoIO( game_io_msg );
  391.  
  392.   /* Return any error message, or 0 if everything is OK: */
  393.   return( game_io_msg->io_Error );
  394. }
  395.  
  396.  
  397.  
  398.  
  399. /*************************************************************/
  400. /*                                                           */
  401. /* SetControllerRead() prepares the system for reading data  */
  402. /* from the selected device, and place the information in    */
  403. /* the data structure.                                       */
  404. /*                                                           */
  405. /* Synopsis: SetControllerRead( data );                      */
  406. /*                                                           */
  407. /* data:     (struct InputEvent *) Pointer to an InputEvent  */
  408. /*           structure which will be filled with information */
  409. /*           when a gameport event occurs.                   */
  410. /*                                                           */
  411. /*************************************************************/
  412.  
  413. void SetControllerRead( data )
  414. struct InputEvent *data;
  415. {
  416.   /* We want to read gameport events: */
  417.   game_io_msg->io_Command = GPD_READEVENT;  
  418.  
  419.   /* The gameport event is sizeof(struct InputEvent) bytes long: */
  420.   game_io_msg->io_Length = sizeof(struct InputEvent);  
  421.  
  422.   /* Where we want the data to be placed: */
  423.   game_io_msg->io_Data = (APTR) data;
  424.  
  425.   /* Read one event each time we go back to the gameport: */
  426.   game_io_msg->io_Flags = 0;
  427. }
  428.  
  429.  
  430.  
  431. /**************************************************************/
  432. /*                                                            */
  433. /* GetControllerType() tells us what type of device (nothing, */
  434. /* absolute joystick, proportional joystick or a mouse) is    */
  435. /* already connected to the Gameport.                         */
  436. /*                                                            */
  437. /* Synopsis: type = GetControllerType();                      */
  438. /*                                                            */
  439. /* type:     (UBYTE) Type of controller connected:            */
  440. /*             GPCT_NOCONTROLLER - nothing                    */
  441. /*             GPCT_MOUSE        - mouse                      */
  442. /*             GPCT_ABSJOYSTICK  - absolute (normal) joystick */
  443. /*             GPCT_RELJOYSTICK  - proportional joystick      */
  444. /*                                                            */
  445. /**************************************************************/
  446.  
  447. BYTE GetControllerType()
  448. {
  449.   BYTE type = 0;
  450.  
  451.   /* We want to know if any controller is already set: */
  452.   game_io_msg->io_Command = GPD_ASKCTYPE;
  453.  
  454.   /* The message is only one byte long: */
  455.   game_io_msg->io_Length = 1;
  456.  
  457.   /* Where we want the data stored: */
  458.   game_io_msg->io_Data = (APTR) &type;  
  459.  
  460.   /* Do our request, and return when it is done: */
  461.   DoIO( game_io_msg );  
  462.  
  463.   /* Return the answer: */
  464.   return( type );
  465. }
  466.  
  467.  
  468.  
  469.  
  470. void clean_up( message )
  471. STRPTR message;
  472. {
  473.   /* Close the gameport device: */
  474.   if( !deviceerror )
  475.   {
  476.     SetControllerType( GPCT_NOCONTROLLER );
  477.     CloseDevice( game_io_msg );
  478.   }
  479.  
  480.   /* Deallocate I/O request block: */
  481.   if( game_io_msg )
  482.     DeleteStdIO( game_io_msg );
  483.  
  484.   /* Close message port: */
  485.   if( game_msg_port )
  486.     DeletePort( game_msg_port );
  487.  
  488.   /* Print message before we quit: */
  489.   printf( "%s\n", message );
  490.  
  491.   /* Quit: */
  492.   exit( 0 );
  493. }
  494.  
  495.  
  496.  
  497.